/*================================================================
*   Copyright (C) 2020 belonging to YangZhengQing. All rights reserved.
*   
*   文件名称：tlv_pack.c
*   创 建 者：YangZhengQing
*   创建日期：2020年03月02日
*   描    述：tlv协议，数据打包
*
*================================================================*/



#include "../include/type.h"
#include "../include/client.h"

#define PACK_SIZE 200


/*
   功能：打包数据
    pp： 待打包的数据
   buff：数据缓存
   size：buff的大小
   返回：成功返回数据包大小，失败返回-1
 */
int tlv_pack(pack_t *pp, char *buff,int size)
{
	int					offset = 0;//缓存区偏移
	int					i;
    int                 len = 0;
	CRC_8				type;//crc类型
	u8					crc;//校验和

	type.poly		= POLYNOMIAL;//多项式
	type.InitValue	= INITVAL;//初始值
	type.xor		= XOR;//异或值
	type.InputReverse = TRUE;
	type.OutputReverse= TRUE;

	//填充数据包
	buff[offset++] = HEAD;//报头
    buff[offset++] = HEAD;

    //填充日期
    if((len = (u8)strlen(pp->s_pack.date)))
    {
        buff[offset++] = TAG_DATE;//数据标签
        buff[offset++] = len;//日期的长度

        for(i = 0; i < len; i++)
        {
            if(offset < size)//防止数组越界
            {
                buff[offset++] = pp->s_pack.date[i];
            }
        }
    }

    //填充时间
    if((len = (u8)strlen(pp->s_pack.time)))
    {
        buff[offset++] = TAG_TIME;//数据标签
        buff[offset++] = len;//日期的长度
        for(i = 0; i < len; i++)
        {
            if(offset < size)
            {
                buff[offset++] = pp->s_pack.time[i];
            }
        }
    }

    //填充设备号
    if((len = (u8)strlen(pp->s_pack.sn)))
    {
        buff[offset++] = TAG_SN;//数据标签
        buff[offset++] = len;//日期的长度
        for(i = 0; i < len; i++)
        {
            if(offset < size)
            {
                buff[offset++] = pp->s_pack.sn[i];
            }
        }
    }
   
    //填充温度
    if((len = (u8)strlen(pp->s_pack.temp)))
    {
        buff[offset++] = TAG_TEMP;//数据标签
        buff[offset++] = len;//日期的长度
        for(i = 0; i < len; i++)
        {
            if(offset < size)
            {
                buff[offset++] = pp->s_pack.temp[i];
            }
        }
    }
    //填充ack
    if((len = (u8)strlen(pp->ack)))
    {
        buff[offset++] = TAG_ACK;//数据标签
        buff[offset++] = len;//日期的长度
        for(i = 0; i < len; i++)
        {
            if(offset < size)
            {
                buff[offset++] = pp->ack[i];
            }
        }
    }
    
    if((len = (u8)strlen(pp->nak)))
    {
        buff[offset++] = TAG_NAK;//数据标签
        buff[offset++] = len;//日期的长度
        for(i = 0; i < len; i++)
        {   if(offset < size)
            {
                buff[offset++] = pp->nak[i];
            }
        }
    }

    
    //填充校验和
    crc = crc8((u8 *)&buff[1], offset-1, type);//CRC校验
    if(offset < size)
    {
        buff[offset++] = TAG_CRC;
        buff[offset++] = 0x01;
        buff[offset++] = crc;


        //填充报文尾
        buff[offset++] = REAR;
        buff[offset]   = REAR;
    }


	return offset;
	
}


/*功能：结构体清零
 * 参数：pp:结构体
 * 返回值:无*/
void memset_pack_struct(pack_t *pp)
{
    memset(pp->s_pack.date,0,sizeof(pp->s_pack.date));
    memset(pp->s_pack.time,0,sizeof(pp->s_pack.time));
    memset(pp->s_pack.sn,0,sizeof(pp->s_pack.sn));
    memset(pp->s_pack.temp,0,sizeof(pp->s_pack.temp));

}

/*功能:判断数据结构体是否为空
 *参数:pp:数据包结构体
 *返回值:为空返回1,不为空返回0
 */
int struct_is_empty(pack_t *pp)
{
    if(!strlen(pp->s_pack.date) || !strlen(pp->s_pack.time) || !strlen(pp->s_pack.sn) || !strlen(pp->s_pack.temp))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}



/*
 功能：数据包解包
 参数：
	data:待解包的数据报文
	pp:解析之后数据缓冲区
 返回：成功返回0，失败返回-1

 */

int tlv_unpack(char *data, pack_t *pp)
{

    int                      rv = 0;
    u8                       *ptr ;
    unsigned char            len;
    unsigned char            i;//不能使用char型做数组下标

   
    ptr = (u8 *)data;
    while(*ptr != TAG_CRC)
    {
        switch(*ptr)
        {
            case TAG_DATE:
            {
                ptr += 1;
                len = *ptr;
                for(i = 0; i < len;i++)
                {
                    ptr++;
                    pp->s_pack.date[i] = *ptr;
                }
                break;
            }
            case TAG_TIME:
            {
                ptr++;
                len = *ptr;
                for(i = 0; i < len; i++)
                {
                    ptr++;
                    pp->s_pack.time[i] = *ptr;
                }
                break;
            }
            case TAG_SN:
            {
                ptr++;
                len = *ptr;
                for(i = 0; i < len;i++)
                {
                    ptr++;
                    pp->s_pack.sn[i] = *ptr;
                }
                break;
            }
            case TAG_TEMP:
            {
                ptr++;
                len = *ptr;
                for(i = 0; i < len;i++)
                {
                    ptr++;
                    pp->s_pack.temp[i] = *ptr;
                }
                break;
            }
            case TAG_ACK:
            {
                ptr++;
                len = *ptr;
                for(i = 0; i < len; i++)
                {
                    ptr++;
                    pp->ack[i] = *ptr;
                }
                rv = TAG_ACK;
                break;
            }
            case TAG_NAK:
            {
                ptr++;
                len = *ptr;
                for(i = 0; i < len; i++)
                {
                    ptr++;
                    pp->nak[i] = *ptr;
                }
                rv = TAG_NAK;
                break;
            }
        }

        ptr++;

    }

    return rv;
}


/* 功能：CRC检验数据包
 * 参数：data:数据包首地址
 * 返回值：成功返回0，失败返回-1*/
int pack_crc(char *data)
{
    u8              *crc_start;
    u8            *crc_end;
    u8              crcval;
    CRC_8           type;

    type.poly       = POLYNOMIAL;//多项式
    type.InitValue  = INITVAL;//初始值
    type.xor        = XOR;//异或值
    type.InputReverse = TRUE;
    type.OutputReverse= TRUE;

    crc_end = (u8 *)data;


    while(*crc_end != TAG_CRC && *crc_end != '\0')
    {
        if(*crc_end == HEAD)
        {
            crc_start = crc_end;
        }
        crc_end++;
    }


    crcval = crc8(crc_start, (crc_end - crc_start), type);
    crc_end += 2;
    if(crcval != *crc_end)
    {
        return CRC_NO;
    }

    return CRC_OK;
}




/*
  功能：计算出数据报文的总长度
  参数：
	data:数据报文
  返回：数据报文长度
 */
int pack_length(char *data)
{
	int				length = 0;

	while(data[length] != REAR)
	{
		length++;
	}

	return length;
}


